package cn.pku.sirx.snad.ad.util;

import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestUtils;

import cn.pku.sirx.snad.ad.Constants;
import cn.pku.sirx.snad.ad.model.UserContext;

/**
 * Convert between UserContext and its string representation.
 * 
 * @author WangXiao
 */
public abstract class UserContextStringUtils {

	/**
	 * Get user context from request.
	 * 
	 * @param request
	 *            HttpServletRequest
	 * @return user context
	 * @throws ServletException
	 */
	public static UserContext toUserContext(HttpServletRequest request)
			throws ServletException {
		Assert.notNull(request);

		UserContext result = new UserContext();
		// user IP
		result.setUserId((String) request.getSession().getAttribute(
				Constants.WEB_P_USER_ID));
		result.setUserIp(request.getRemoteAddr());
		// extract keys and values
		setUserContext(result, ServletRequestUtils.getStringParameter(request,
				Constants.WEB_P_USER_CONTEXT));
		return result;
	}

	/**
	 * Get user context string from user context.
	 * 
	 * @param userContext
	 *            UserContext
	 * @return user context string
	 */
	public static String toUserContextString(UserContext userContext) {
		Assert.notNull(userContext);

		// extract keys and values
		return String.format("%s=%s", Constants.WEB_P_USER_ID, userContext
				.getUserId()); // currently nothing to do
	}

	/*
	 * package access-able for test
	 */
	static void setUserContext(UserContext userContext, String userContextString) {
		if (userContextString == null) {
			return;
		}
		userContextString = EncryptUtils.decrypt(userContextString);
		StringTokenizer stringTokenizer = new StringTokenizer(
				userContextString, WEB_USER_CONTEXT_PAIR_SEPRATOR);
		while (stringTokenizer.hasMoreElements()) {
			String token = (String) stringTokenizer.nextElement();
			String[] pair = StringUtils.tokenizeToStringArray(token,
					WEB_USER_CONTEXT_KEY_VALUE_SEPRATOR);
			if (pair.length == 2) {
				setUserContext(userContext, pair[0], pair[1]);
			}
		}
	}

	private static void setUserContext(UserContext userContext, String key,
			String value) {
		if (key.equals(Constants.WEB_P_USER_ID)) {
			userContext.setUserId(value);
		}
	}

	private static String WEB_USER_CONTEXT_PAIR_SEPRATOR = " ";

	private static String WEB_USER_CONTEXT_KEY_VALUE_SEPRATOR = "=";

}
